package cn.fl.upgrade.service.impl;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.*;

import cmm.comm.facade.upgrade.dto.SysAppVerRuleDTO;
import cn.cmm.base.framework.constant.BaseConstant;
import cn.fl.system.api.ISysSequenceApiService;
import cn.fl.upgrade.transform.SysAppVerRuleVOTransform;
import cn.fl.upgrade.vo.SysAppVerRuleVO;
import com.alibaba.fastjson.JSON;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import com.alibaba.fastjson.JSONObject;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.model.PutObjectResult;

import cmm.comm.facade.framework.api.ISysDictionaryApiService;
import cmm.comm.facade.upgrade.api.IUpgradeApiService;
import cmm.comm.facade.upgrade.condition.SysAppVerCfgQueryCondition;
import cmm.comm.facade.upgrade.dto.SysAppVerCfgDTO;
import cmm.mid.core.framework.page.KeyValueVO;
import cmm.mid.core.framework.page.Pager;
import cn.cmm.base.framework.constant.BaseExceptionConstant;
import cn.cmm.base.framework.exception.BaseException;
import cn.cmm.base.framework.utils.BaseLogUtils;
import cn.cmm.base.framework.utils.CollectionUtils;
import cn.cmm.base.framework.utils.DateUtils;
import cn.cmm.base.framework.utils.StringUtils;
import cn.cmm.cache.framework.utils.PropertiesCacheUtils;
import cn.fl.framework.base.context.CurrentThreadContext;
import cn.fl.upgrade.service.ISysAppVerCfgService;
import cn.fl.upgrade.transform.SysAppVerCfgVOTransform;
import cn.fl.upgrade.vo.SysAppVerCfgVO;

/**
 * @Description: 移动APP版本配置表 客户端服务层接口实现
 * @Description: 业务层方法名称前缀：新增：add* 删除：remove* 修改：modify* 查询对象：select* get* 批量：batch* 查询集合：search*
 */
@Service
public class SysAppVerCfgServiceImpl implements ISysAppVerCfgService {

	/**
	 * 日志
	 */
	private static final Logger logger = LoggerFactory.getLogger(ISysAppVerCfgService.class);
	
	@Autowired
	private IUpgradeApiService upgradeApiService;

	/**
	 * 数据字典服务
	 */
	@Autowired
	private ISysDictionaryApiService sysDictionaryApiService;

	@Autowired
	private ISysSequenceApiService sysSequenceApiService;

	@Override
	public SysAppVerCfgVO selectById(Long id) throws BaseException{
		if(StringUtils.isEmpty(id)){
			BaseLogUtils.info(logger, "selectById", "主键参数不能为空!", CurrentThreadContext.getCurrentUserName());
			return null;
		}
		SysAppVerCfgDTO dto = this.upgradeApiService.selectSysAppVerCfgById(id);
		return SysAppVerCfgVOTransform.toVO(dto);
	}

	@Override
	public Long add(SysAppVerCfgVO entity,String traceId) throws BaseException{
		if(null == entity){
			BaseLogUtils.info(logger, "add", "新增对象不能为空!", CurrentThreadContext.getCurrentUserName());
			return null;
		}
		Long id= this.upgradeApiService.addSysAppVerCfg(SysAppVerCfgVOTransform.toDTO(entity));
		if(StringUtils.isNotEmpty(id)){
			this.addVerRuleList(id,entity.getSysAppVerRuleVOList(),traceId);
		}
		return id;
	}

	@Override
	public boolean removeById(Long id) throws BaseException{
		if(StringUtils.isEmpty(id)){
			BaseLogUtils.info(logger, "removeById", "删除主键参数不能为空!", CurrentThreadContext.getCurrentUserName());
			return false;
		}
		//return this.sysAppVerCfgApiService.removeById(id);
		return false;
	}

	
	/**
     * 删除
     * @param ids
     * @return
     */
	@Override
    public boolean removeByIds(List<Long> ids)throws BaseException{
    	if(CollectionUtils.isEmpty(ids)){
    		BaseLogUtils.info(logger, "removeByIds", "删除主键参数集合不能为空!", CurrentThreadContext.getCurrentUserName());
			return false;
		};
		return false;
    }

	@Override
	public boolean modify(SysAppVerCfgVO entity,String traceId) throws BaseException{
		if(null == entity){
			BaseLogUtils.info(logger, "modify", traceId+"修改对象参数不能为空!", CurrentThreadContext.getCurrentUserName());
			return false;
		}
		boolean rtn= this.upgradeApiService.modifySysAppVerCfg(SysAppVerCfgVOTransform.toDTO(entity));
        BaseLogUtils.info(logger, "modify", traceId+"修改对象结果："+rtn, CurrentThreadContext.getCurrentUserName());

        if(rtn && CollectionUtils.isNotEmpty(entity.getSysAppVerRuleVOList())){
			rtn=this.addVerRuleList(entity.getId(),entity.getSysAppVerRuleVOList(),traceId);
		}
		return rtn;
	}

	@Override
	public List<SysAppVerCfgDTO> searchList(SysAppVerCfgQueryCondition condition) throws BaseException {
    	if (null == condition) {
			BaseLogUtils.info(logger, "searchList", "查询条件不能为空!", CurrentThreadContext.getCurrentUserName());
    		return null;
		}
		return this.upgradeApiService.searchSysAppVerCfgList(condition);
	}

	@SuppressWarnings("unchecked")
	@Override
	public Pager searchListPage(Pager page) throws BaseException{
		if(null == page){
			return new Pager();
		}
		Pager resultpager = this.upgradeApiService.searchSysAppVerCfgListPage(page);
		List<SysAppVerCfgVO> list = SysAppVerCfgVOTransform.toVOList((List<SysAppVerCfgDTO>)resultpager.getResultList());
		resultpager.setResultList(list);
		return resultpager;
	}
	@Override
	public Map<String, String> searchGroupToMap(String sysCd, String orgCd, String codeGrpCd) throws BaseException{
		return this.sysDictionaryApiService.searchGroupToMap(sysCd, orgCd, codeGrpCd);
	}

	@Override
	public List<KeyValueVO> getKvList(String codeGrpCd, String sysCd, String orgCd) throws BaseException {
		return this.sysDictionaryApiService.getKvList(codeGrpCd,sysCd,orgCd);
	}

	@Override
	public List<KeyValueVO> getKvListWithAttr1(String grpCd, String filterCodeAttr1, String sysCd, String orgCd) throws BaseException {
		return this.sysDictionaryApiService.getKvListWithAttr1(grpCd, filterCodeAttr1, sysCd, orgCd);
	}
	@Override
	public List<KeyValueVO> getKvListWithAttr1AndAttr2(String grpCd, String filterCodeAttr1,String filterCodeAttr2, String sysCd, String orgCd) throws BaseException {
		return this.sysDictionaryApiService.getKvListWithAttr1AndAttr2(grpCd, filterCodeAttr1,filterCodeAttr2, sysCd, orgCd);
	}
	
	@Override
	public SysAppVerCfgDTO getSysAppVerCfg(SysAppVerCfgQueryCondition condition) throws BaseException {
		List<SysAppVerCfgDTO> list = this.upgradeApiService.searchUpgradeVersionList(condition);
		if(CollectionUtils.isNotEmpty(list)){
			return list.get(0);
		}
		return null;
	}

	@Override
	public SysAppVerCfgDTO getUpgradeAppVer(SysAppVerCfgQueryCondition condition) throws BaseException {
		List<SysAppVerCfgDTO> list = this.upgradeApiService.searchUpgradeVerList(condition);
		if(CollectionUtils.isNotEmpty(list)){
			return list.get(0);
		}
		return null;
	}

	/**
     * @param file
     * @return
     * @throws Exception
     */
    @Override
    public String uploadToOss(MultipartHttpServletRequest multipartRequest,String sysCd,String opTypCd,String verNo) throws BaseException {
    	Iterator<String> iter = multipartRequest.getFileNames();
		// 如果没有文件 抛出异常
		if (!iter.hasNext()) {
			BaseLogUtils.info(logger, "fileUpload", "文件上传失败,未选中文件内容.", CurrentThreadContext.getCurrentUserName());
			throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_600, "请选择要上传的文件!");
		}
		String serverPrefixPath = PropertiesCacheUtils.getProperty("ulfiles.ossulfiles.properties.type");
        String endPoint = PropertiesCacheUtils.getProperty("ulfiles.ossulfiles.properties.endpoint");
        String ossAccessKeyId = PropertiesCacheUtils.getProperty("ulfiles.ossulfiles.properties.ossaccesskeyid");
        String ossSecret = PropertiesCacheUtils.getProperty("ulfiles.ossulfiles.properties.osssecret");
        String bucketName = PropertiesCacheUtils.getProperty("ulfiles.ossulfiles.properties.bucketname");
        String baseName = PropertiesCacheUtils.getProperty("ulfiles.ossulfiles.properties.basename");
        String domainName = PropertiesCacheUtils.getProperty("ulfiles.ossulfiles.properties.domainname");
        String currentTime = DateUtils.formatDateToString(new Date(), DateUtils.YYYYMMDD);
        String prefix="";
        String key="";
        
     // 创建OSSClient实例
        OSSClient ossClient = new OSSClient(endPoint, ossAccessKeyId, ossSecret);
        prefix = serverPrefixPath+"/" +sysCd+"/"+baseName +"/"+currentTime;
		while (iter.hasNext()) {
			// 取得上传文件
			List<MultipartFile> fileList = multipartRequest.getFiles(iter.next());
			for (MultipartFile f : fileList) {
				if (f != null) {
					// 取得当前上传文件的文件名称
					String myFileName = f.getOriginalFilename();
					// 取得当前上传文件的大小
					// Long size = f.getSize();
					// 如果名称不为"",说明该文件存在，否则说明该文件不存在
					if (StringUtils.isNotEmpty(myFileName)) {
						try{
							// 上传文件流
					        String[] endName=myFileName.split("\\.");
					        key =prefix+"/"+System.currentTimeMillis()+"."+endName[endName.length-1];
					        BaseLogUtils.info(logger, "uploadToOss", "上传阿里云 key="+key);
					        PutObjectResult puobj = ossClient.putObject(bucketName, key, f.getInputStream()); 
					        BaseLogUtils.info(logger, "uploadToOss", "上传阿里云 成功 puobj="+JSONObject.toJSONString(puobj));
						} catch (BaseException ex) {
							BaseLogUtils.info(logger, "uploadToOss", "文件上传失败.ERROR", CurrentThreadContext.getCurrentUserName(),ex);
							throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_600, ex.getMessage());
						} catch (Exception ex) {
							BaseLogUtils.error(logger, "uploadToOss", "文件上传失败,系统错误.ERROR" ,CurrentThreadContext.getCurrentUserName(), ex);
							throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_600, "系统异常!");
						}
					}
				}
			}
		}
		//根据设备类型判断如果是ios需要处理plist
		if("1".equals(opTypCd) && StringUtils.isNotEmpty(key)){
			String root = PropertiesCacheUtils.getProperty("ulfiles.ulfiles.properties.root.path");
            String costomer = PropertiesCacheUtils.getProperty("ulfiles.ulfiles.properties.costomer.path");
            //获取ios安装包路径
            String servePath = domainName+"/"+key;
            //读取文件内容并修改
            String url = root + costomer + "app/Lionbridge2.plist";
            //读取原始plist模板内容
            String content = this.read(url, servePath, verNo, sysCd);
            //根据原始plist模板文件重新生成新的plist文件防止缓存出现
            String newurl = url.substring(0, url.lastIndexOf("/")) + servePath.substring(servePath.lastIndexOf
                    ("/"), servePath.lastIndexOf(".")) + ".plist";
            //将修改后的文件内容重新写入文件
            this.write(newurl, content);
            File plistFile = new File(newurl);
            key =prefix+"/"+"plist"+"/"+System.currentTimeMillis()+"."+"plist";
            try{
            	PutObjectResult puobj = ossClient.putObject(bucketName, key, plistFile); 
                BaseLogUtils.info(logger, "uploadToOss", "上传阿里云 成功 plist puobj="+JSONObject.toJSONString(puobj));
            } catch (BaseException ex) {
				BaseLogUtils.info(logger, "uploadToOss", "文件上传失败.ERROR", CurrentThreadContext.getCurrentUserName(),ex);
				throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_600, ex.getMessage());
			} catch (Exception ex) {
				BaseLogUtils.error(logger, "uploadToOss", "文件上传失败,系统错误.ERROR" ,CurrentThreadContext.getCurrentUserName(), ex);
				throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_600, "系统异常!");
			}
		}
        // 关闭client
        ossClient.shutdown();
        if(StringUtils.isNotEmpty(key)){
        	return domainName+"/"+key;
        }else{
        	return null;
        }
    }

    @Override
    public Long getVerId() throws BaseException {
        return this.sysSequenceApiService.getSeq("SEQ_SYS_APP_VER_CFG_VER_ID_ID");
    }

	/**
	 * @MethodName selectMaxVerId
	 * @Description: 查询最大的编号信息
	 * @Author: wangpengtao@lionbridgecapital.cn
	 * @CreateDate: 2019/11/25 14:43
	 * @Version: V1.0.0
	 * @Param opTypCd
	 * @Param sysCd
	 * @Return java.lang.Integer
	 * @UpdateRemark [序号][YYYY-MM-DD] [更改人姓名][变更描述]
	 */
	@Override
	public Integer selectMaxVerId(String opTypCd,String sysCd) throws BaseException{
		return this.upgradeApiService.selectMaxVerId(opTypCd, sysCd);
	}

	/**
	 * @MethodName selectMaxVerId
	 * @Description: 查询最大的编号后设置
	 * @Author: wangpengtao@lionbridgecapital.cn
	 * @CreateDate: 2019/11/25 14:43
	 * @Version: V1.0.0
	 * @Param opTypCd
	 * @Param sysCd
	 * @Return java.lang.Integer
	 * @UpdateRemark [序号][YYYY-MM-DD] [更改人姓名][变更描述]
	 */
	@Override
	public List<SysAppVerRuleDTO> selectMaxVerList(Integer verId,String opTypCd, String sysCd) throws BaseException{
		return this.upgradeApiService.selectMaxVerList(verId, opTypCd, sysCd);
	}

	/**
	 * @MethodName addVerRuleList
	 * @Description: 批量新增更新规则
	 * @Author: wangpengtao@lionbridgecapital.cn
	 * @CreateDate: 2019/11/20 9:34
	 * @Version: V1.0.0
	 * @Param sysAppVerRuleVOList
	 * @Return boolean
	 * @UpdateRemark [序号][YYYY-MM-DD] [更改人姓名][变更描述]
	 */
	private boolean addVerRuleList(Long cfgId, List<SysAppVerRuleVO> sysAppVerRuleVOList,String traceId) throws BaseException {
        BaseLogUtils.info(logger, "addVerRuleList", traceId+"添加版本规则请求参数cfgId："+cfgId, CurrentThreadContext.getCurrentUserName());
        BaseLogUtils.info(logger, "addVerRuleList", traceId+"添加版本规则请求参数sysAppVerRuleVOList："+ JSON.toJSONString(sysAppVerRuleVOList), CurrentThreadContext.getCurrentUserName());

        if (StringUtils.isEmpty(cfgId)) {
            BaseLogUtils.info(logger, "addVerRuleList", traceId+"添加版本规则失败 cfgId is null", CurrentThreadContext.getCurrentUserName());
            return false;
		}
        try {
            if (CollectionUtils.isNotEmpty(sysAppVerRuleVOList)) {
                for (SysAppVerRuleVO sysAppVerRuleVO : sysAppVerRuleVOList) {
                	sysAppVerRuleVO.setCfgId(cfgId);
                    sysAppVerRuleVO.setIsDel(BaseConstant.IS_YESNO_NO);
                    sysAppVerRuleVO.setCrtTm(new Date());
                    sysAppVerRuleVO.setCrtUsrId(CurrentThreadContext.getCurrentUserId());
                }
                BaseLogUtils.info(logger, "addVerRuleList", traceId+"删除原有规则处理开始", CurrentThreadContext.getCurrentUserName());
                SysAppVerRuleDTO delDTO = new SysAppVerRuleDTO();
                delDTO.setMdfTm(new Date());
                delDTO.setMdfUsrId(CurrentThreadContext.getCurrentUserId());
                delDTO.setCfgId(cfgId);
                this.upgradeApiService.delSysAppVerRule(delDTO);
                BaseLogUtils.info(logger, "addVerRuleList", traceId+"删除原有规则处理结束", CurrentThreadContext.getCurrentUserName());
                BaseLogUtils.info(logger, "addVerRuleList", traceId+"删除新规则处理开始", CurrentThreadContext.getCurrentUserName());
                this.upgradeApiService.addSysAppVerRuleBatch(SysAppVerRuleVOTransform.toDTOList(sysAppVerRuleVOList));
                BaseLogUtils.info(logger, "addVerRuleList", traceId+"删除新规则处理结束", CurrentThreadContext.getCurrentUserName());
            }
        }catch (BaseException e){
            BaseLogUtils.error(logger, "addVerRuleList", traceId+"添加版本规则请求参数处理异常"+e.getMessage(),e);
            BaseLogUtils.info(logger, "addVerRuleList", traceId+"添加版本规则请求参数处理异常"+e.getMessage());
            throw new BaseException(e.getMessage());
        }catch (Exception e){
            BaseLogUtils.error(logger, "addVerRuleList", traceId+"添加版本规则请求参数处理异常"+e.getMessage(),e);
            BaseLogUtils.info(logger, "addVerRuleList", traceId+"添加版本规则请求参数处理异常"+e.getMessage());
            throw new BaseException(e.getMessage());
        }
        BaseLogUtils.info(logger, "addVerRuleList", traceId+"添加版本规则请求参数处理成功", CurrentThreadContext.getCurrentUserName());
        return true;
	}


	/**
     * 读取文件
     *
     * @param filePath
     * @return
     */
    private String read(String filePath, String ipa, String verNo, String sysCd) {
        String text = "";
        String dire = "";
        String packageStr = "";
        if ("11002".equals(sysCd)) {
            text = "狮桥助手";
            dire = "sqhelper";
            packageStr = "com.lionbridge.helper";
        } else if ("11003".equals(sysCd)) {
            text = "狮桥在线";
            dire = "sqonline";
            packageStr = "com.shiqiao.Tenant";
        } else if ("11004".equals(sysCd)) {
            text = "狮桥汽车";
            dire = "sqcar";
            packageStr = "com.lionbridgecapital.lionbridgecars";
        } else if ("11005".equals(sysCd)) {
            text = "狮桥商家";
            dire = "sqshop";
            packageStr = "com.lionbridge.distributor";
        } else if ("11006".equals(sysCd)) {
            text = "狮桥助手管理版";
            dire = "sqhelpermgt";
            packageStr = "com.lionbridge.manage";
        }
        BufferedReader br = null;
        String line = null;
        StringBuffer buf = new StringBuffer();

        try {
            // 根据文件路径创建缓冲输入流
            br = new BufferedReader(new FileReader(filePath));
            int i = 1;
            // 循环读取文件的每一行, 对需要修改的行进行修改, 放入缓冲对象中
            while ((line = br.readLine()) != null) {
                if (i == 14) {
                    line = line.substring(0, line.indexOf("<string>") + 8) + ipa + "</string>";
                } else if (i == 22) {
                    line = line.substring(0, line.indexOf("sqcar")) + dire + "/icon@2x.png</string>";
                } else if (i == 30) {
                    line = line.substring(0, line.indexOf("sqcar")) + dire + "/icon@3x.png</string>";
                }else if (i == 36) {
                    line = line.substring(0, line.indexOf("<string>") + 8) + packageStr + "</string>";
                } else if (i == 38) {
                    line = line.substring(0, line.indexOf("<string>") + 8) + verNo + "</string>";
                } else if (i == 42) {
                    line = line.substring(0, line.indexOf("<string>") + 8) + text + "</string>";
                }
                buf.append(line);
                buf.append(System.getProperty("line.separator"));
                i++;
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 关闭流
            if (br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                    br = null;
                }
            }
        }
        return buf.toString();
    }

    /**
     * 写入内容
     *
     * @param filePath
     * @param content
     */
    private void write(String filePath, String content) {
        BufferedWriter bw = null;
        try {
            // 根据文件路径创建缓冲输出流
            bw = new BufferedWriter(new FileWriter(filePath));
            // 将内容写入文件中
            bw.write(content);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 关闭流
            if (bw != null) {
                try {
                    bw.close();
                } catch (IOException e) {
                    bw = null;
                }
            }
        }
    }
}
